package
{
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundLoaderContext;
	import flash.net.URLRequest;
	import flash.sampler.getInvocationCount;
	import flash.text.TextField;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	import mx.collections.ArrayList;
	
	import org.osmf.elements.SoundLoader;
	
	public class Jogo extends Sprite
	{
		
		public static const SPACING:Number = 72;
		public static const COLUNMS:Number = 8;
		public static const ROWS:Number = 4;
		public static const X_INICIAL:int = 116;
		public static const Y_INICIAL:int = 50;
		public static const IMG_PATH:String = "./assets/img";
		public static const START_BUTTON_URL:String = "./assets/start-button.png";
		public static const STOP_BUTTON_URL:String = "./assets/stop-button.png";
		public static const IMG_EXTENSION:String = ".png";
		public static const ANDROID_URL_REQ:URLRequest = new URLRequest("./assets/android.png");
		public static const SOUND_FAIL:String = "./assets/fail-trumpet.mp3";
		public static const SOUND_SUCCESS:String = "./assets/success-beep.mp3";
		
		
		private var partida:Partida;
		private var numCartasViradas:Number;
		private var cartasViradas:Array;
		private var txtScore:TextField;
		private var podeClicar:Boolean;
		private var sound:Sound;
		
		public function Jogo()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			iniciarJogo();
			
		}
		
		private function showStartScreen():void
		{
			var UrlReq:URLRequest = new URLRequest(START_BUTTON_URL);
			var loader:Loader = new Loader();
			loader.addEventListener(MouseEvent.CLICK, init);
			loader.x = (stage.stageWidth / 2) - 164;
			loader.y = (stage.stageHeight / 2) - 164;
			loader.name = "startButton";
			loader.load(UrlReq);
			addChild(loader);
			
		}
		
		private function init(evt:Event):void
		{
			showImages();
			setTimeout(populateImgGrid, 10000);
		}
		
		private function showImages():void
		{
			var imgCount:int = 0;
			
			var startButton:DisplayObject = getChildByName("startButton") as DisplayObject;
			removeChild(startButton);
			
			addChild(txtScore);
			
			do 
			{
				for (var i:int = 0; i < ROWS; i++) 
				{
					var y:int = Y_INICIAL + (i*SPACING);
					for (var j:int = 0; j <COLUNMS; j++) 
					{
						var x:int = X_INICIAL + (j*SPACING);
						trace("Image position " + imgCount + " = (" + x + "," + y + ")");
						
						// Cria loader para a carta, seta os atributos de posição e nome e adiciona ao stage
						var cartaLoader:Loader = new Loader();
						cartaLoader.name = imgCount.toString(); // o nome da carta é um número de 0 a 31, representando os índices de randomizedArray
						trace("Numero da imagem em randArray: " + partida.randomizedArray[cartaLoader.name]);
						cartaLoader.load(new URLRequest(IMG_PATH + partida.randomizedArray[cartaLoader.name] + IMG_EXTENSION));
						cartaLoader.x = x;
						cartaLoader.y = y;
						imgCount++;
						addChild(cartaLoader);
						trace("Quantidade de imagens: " + imgCount);
						
					}
				}
			} while(imgCount < partida.randomizedArray.length);
		}
		
		private function populateImgGrid():void
		{
			for (var k:int = 0; k < partida.randomizedArray.length; k++) 
			{
				removeChild(getChildByName(k.toString()));
			}
			
			var imgLoader:Loader = new Loader();
			imgLoader.x = (stage.stageWidth / 2) - 36;
			imgLoader.y = 350; 
			imgLoader.name = "stopBtn";
			imgLoader.load(new URLRequest(STOP_BUTTON_URL));
			imgLoader.addEventListener(MouseEvent.CLICK, encerrarJogo);
			addChild(imgLoader);	
			
			var imgCount:int = 0;
			
			do 
			{
				for (var i:int = 0; i < ROWS; i++) 
				{
					var y:int = Y_INICIAL + (i*SPACING);
					for (var j:int = 0; j <COLUNMS; j++) 
					{
						var x:int = X_INICIAL + (j*SPACING);
						trace("Image position " + imgCount + " = (" + x + "," + y + ")");
						
						// Cria loader para a carta, seta os atributos de posição e nome e adiciona ao stage
						var cartaLoader:Loader = new Loader();
						cartaLoader.name = imgCount.toString(); // o nome da carta é um número de 0 a 31, representando os índices de randomizedArray
						trace("Numero da imagem em randArray: " + partida.randomizedArray[cartaLoader.name]);
						cartaLoader.load(ANDROID_URL_REQ);
						cartaLoader.addEventListener(MouseEvent.CLICK, virarCarta);
						cartaLoader.x = x;
						cartaLoader.y = y;
						imgCount++;
						addChild(cartaLoader);
						trace("Quantidade de imagens: " + imgCount);
						
					}
				}
			} while(imgCount < partida.randomizedArray.length);
		}

		private function virarCarta(evt:Event):void
		{
			if (podeClicar) 
			{
				
				numCartasViradas += 1;
					
				if (numCartasViradas <= 2) 
				{
				var carta:DisplayObject = evt.target as DisplayObject;
				var x_pos:int = carta.x;
				var y_pos:int = carta.y;
				var index:String = carta.name;
				trace("Indice da carta clicada: " + index);
				var stageIndex:int = getChildIndex(carta);
				
				removeChildAt(stageIndex);
				
				var cartaUrlReq:URLRequest = new URLRequest(IMG_PATH + partida.randomizedArray[index] + IMG_EXTENSION);
				var cartaLoader:Loader = new Loader();
				
				cartaLoader.load(cartaUrlReq);
				cartaLoader.name = index;
				cartaLoader.x = x_pos;
				cartaLoader.y = y_pos;
				
				addChildAt(cartaLoader, stageIndex);//
				
				cartasViradas[numCartasViradas - 1] = cartaLoader.name;
				
				trace("Cartas viradas: " + numCartasViradas);
					
				}
				
				if (numCartasViradas == 2) 
				{
					podeClicar = false;
					
					if (!isImagePair()) 
					{
						errar();
					} else {
						acertar();
					}
				}
		}
			}
		
		private function errar():void
		{
			trace("Cartas viradas nao formam par");
			partida.missPt();
			trace("Score: " + partida.score)
			txtScore.text = "Score: " + partida.score + " %";
			numCartasViradas = 0;
			playAudio(SOUND_FAIL);
			setTimeout(desvirarCartas, 2600);
		}
		
		private function acertar():void
		{
			trace("Cartas viradas FORMARAM par");
			partida.winPt();
			playAudio(SOUND_SUCCESS);
			txtScore.text = "Score: " + partida.score + " %";
			trace("Score: " + partida.score)
			numCartasViradas = 0;
			cartasViradas = new Array();;
			podeClicar = true;
			
				if (partida.numAcertos == 16) 
				{
					var evt:Event = new Event(null);
					encerrarJogo(evt);
				
				}
		}

		private function isImagePair():Boolean
		{
			
			for (var i:int = 0; i < cartasViradas.length; i++) 
			{
				trace("Object " + i + ": " + cartasViradas[i]);
			}
			
			var indexCartaVirada1:int = cartasViradas[0];
			trace("Indice da primeira carta virada" + indexCartaVirada1);
			var indexCartaVirada2:int = cartasViradas[1];
			trace("Índice da segunda carta virada" + indexCartaVirada2);
			if (partida.randomizedArray[indexCartaVirada1] == partida.randomizedArray[indexCartaVirada2]) 
			{
				return true;
			} else {
				return false;
			}
			
		}
	
		private function desvirarCartas():void
		{
			trace("entrou no desvirar cartas" + cartasViradas.length);
			for (var i:int = 0; i < cartasViradas.length; i++) 
			{
				var carta:DisplayObject = getChildByName(cartasViradas[i]);
				var x_pos:int = carta.x;
				var y_pos:int = carta.y;
				var cartaName:String = carta.name;
				var stageIndex:int = getChildIndex(carta);
				removeChildAt(stageIndex);
				
				var cartaLoader:Loader = new Loader();
				cartaLoader.load(ANDROID_URL_REQ);
				cartaLoader.name = cartaName;
				cartaLoader.x = x_pos;
				cartaLoader.y = y_pos;
				cartaLoader.addEventListener(MouseEvent.CLICK, virarCarta);
				addChildAt(cartaLoader, stageIndex);
				
			}
			cartasViradas = new Array();
			podeClicar = true;
			
		}
			
		private function encerrarJogo(evt:Event):void
		{
			var txtLabel:TextField = new TextField();
			txtLabel.x = 116;
			txtLabel.y = 340;
			txtLabel.width = 300;
			txtLabel.name = "txtLabel";
			txtLabel.text = "Jogo encerrado. Seu score foi: " + partida.score + "%.";
			addChild(txtLabel);
			setTimeout(removeAllChildren, 4000);
			setTimeout(iniciarJogo, 4000);
		}
		
		private function iniciarJogo():void
		{
			partida = new Partida();
			cartasViradas = new Array();
			numCartasViradas = 0;
			podeClicar = true;
			
			cartasViradas = new Array();
			
			txtScore = new TextField();
			txtScore.x = 20;
			txtScore.y = 20;
			txtScore.name = "txtScore";
			txtScore.text = new String(txtScore.text = "Score: " + partida.score + " %");
			
			showStartScreen();
			
		}
		
		private function removeAllChildren():void
		{
			removeChild(getChildByName("txtScore"));
			removeChild(getChildByName("txtLabel"));
			removeChild(getChildByName("stopBtn"));
			
			for (var i:int = 0; i < 32; i++) 
			{
				removeChild(getChildByName(i.toString()));
					
			}
			
		}
		
		private function playAudio(soundPath:String):void
		{
			var req:URLRequest = new URLRequest(soundPath);
			var context:SoundLoaderContext = new SoundLoaderContext();
			sound = new Sound(req, context);
			
			sound.play();
			
		}
		
		private function stopAudio(evt:Event):void
		{
			sound.close();
		}
	
	}
	
}